package entjava.poker.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;

import entjava.poker.service.ComboService;
import entjava.poker.service.SmallBigService;

public class Game {
	
	private ArrayList<Player> pl;   //the list of players on start game
	private int playerNumber;
	private Player currentPlayer;
	private boolean gameStarted;
    private int minimumBet;
	private int smallBlind; //small blind number
	private int bigBlind;	//big blind number
	private int dealerNumber; //next dealer 
	private int pot;
    private boolean notOver;
    private Player smallPlayer, bigPlayer, dealerPlayer;
    private int raiseBet;
    private boolean bettingRound;
    private int countRounds;
    private Card c1, c2, c3, c4, c5, first, second;
    private ArrayList rankList = new ArrayList();
    private Deck deck;
    private SmallBigService sbs;
    private boolean resetGame;
    
	public Game(ArrayList<Player> player,SmallBigService sb ) { 
		this.sbs=sb;
		this.pl = player;
		this.playerNumber = 0;
	//	this.currentPlayer = pl.get(getPlayerNumber()); 
		this.currentPlayer = pl.get(sb.getDealerNumber()); 
		this.gameStarted = false;
		this.smallBlind = 1; 
		this.bigBlind = 2;
		this.dealerNumber = 0;
	//	this.smallPlayer = pl.get(getSmallBlind());
		this.smallPlayer = pl.get(sb.getSmallBlind()); 
	//	this.bigPlayer = pl.get(getBigBlind());
		this.bigPlayer=pl.get(sb.getBigBlind());
		this.bettingRound = true;
		this.countRounds=0;
		this.notOver=true;
		this.minimumBet=20;			//preset 20 
		this.deck= new Deck();
		deck.shuffleCard();
		this.resetGame=false;
	}
	
	public void assignInitalCards(){
		for(int i = 0; i<pl.size(); i++){
			first = deck.drawCard();
			second = deck.drawCard();
			for(int x= 0; x<1; x++){
				pl.get(i).getHand().add(first);
				pl.get(i).getHand().add(second);
			}
		}
	}
	
	public void doBettingChoice(String choice){
		
		if(choice.contains("call")){
			System.out.println("Player " +this.getCurrentPlayer().getName() + " call");
	
				int diff=minimumBet-this.getCurrentPlayer().getBet();
				
				//take off difference minimum bet with current bet of current player
				this.getCurrentPlayer().setMoney(this.getCurrentPlayer().getMoney()-diff);
				this.getCurrentPlayer().setBet(minimumBet);				//set bet
				
				//add his money to pot
				pot += diff;			
				this.nextActivePlayers();
				
		}else if(choice.contains("check")){		
			System.out.println("Player " +this.getCurrentPlayer().getName() + " check");
			
			this.getCurrentPlayer().setHasCheck(true); //make that current player has checked

			int countcheck=0;
			for(int i =0; i<pl.size(); i++){				//check if all have checked 
				if(pl.get(i).isHasCheck() || pl.get(i).isHasFolded()){
					countcheck++;
				}
			}		
		
			if(countcheck==pl.size()){
				this.setCountRounds(this.getCountRounds()+1); //count round changes
				checkRounds();
			}
		
			this.nextActivePlayers();
			
		}else if(choice.contains("fold")){
			System.out.println("Player " +this.getCurrentPlayer().getName() + " folded");
			
			this.getCurrentPlayer().setHasFolded(true); 
			
//to do			//check player list if there's only one active player, then that player wins
			int countcheck=0; int countactive=0;
			
			for(int i =0; i<pl.size(); i++){				//check if all have checked 
				if(pl.get(i).isHasCheck() || pl.get(i).isHasFolded()){
					countcheck++;
				}
				if(pl.get(i).isHasFolded()==false){
					countactive++;
				}
			}
			if(countactive==1){
				this.nextActivePlayers();
				this.getCurrentPlayer().win(pot);   //that player win's the pot
				this.getCurrentPlayer().getHand().setCom("By Default");
				this.getCurrentPlayer().setWinner(true);
				this.setNotOver(false);
				
			}else{
				this.nextActivePlayers();		
			}
						
		}else if(choice.contains("raise")){
			System.out.println("Player " +this.getCurrentPlayer().getName() + " raised");
			
			int mone= minimumBet+raiseBet;
	//		this.getCurrentPlayer().setMoney(this.getCurrentPlayer().getMoney()-mone);
			this.getCurrentPlayer().setMoney(this.getCurrentPlayer().getMoney()-raiseBet);
			this.setMinimumBet(mone);
		
			//add his money to pot
			pot += raiseBet;
			
			//set bet
			this.getCurrentPlayer().setBet(minimumBet);
			
			this.nextActivePlayers();	
		}
	}
	
	public void checkRounds(){	
	
		switch(this.getCountRounds()){
		case 1://show all players three cards
			//show three cards on table
			//draw three cards and add those cards to all of the players hands
	
			this.c1 =	deck.drawCard();
			this.c2 =	deck.drawCard();
			this.c3 =	deck.drawCard();
			
			for(int i =0; i<pl.size(); i++){				//add to all players hands
				pl.get(i).getHand().add(c1);
				pl.get(i).getHand().add(c2);
				pl.get(i).getHand().add(c3);
			}
		
			for(int i =0; i<pl.size(); i++){			
				pl.get(i).setHasCheck(false);
			}
			System.out.println("has entered case 1, Three cards on table");
			break;
		case 2:
			this.c4 =	deck.drawCard();
			
			for(int i =0; i<pl.size(); i++){				//add to all players hands
				pl.get(i).getHand().add(c4);
			}
		
			for(int i =0; i<pl.size(); i++){			
				pl.get(i).setHasCheck(false);
			}
			System.out.println("has entered case 2, Four cards on table");
			break;
		case 3:	
			this.c5 =	deck.drawCard();
			
			for(int i =0; i<pl.size(); i++){				//add to all players hands
				pl.get(i).getHand().add(c5);
			}
		
			for(int i =0; i<pl.size(); i++){			
				pl.get(i).setHasCheck(false);
			}	
			System.out.println("has entered case 3, Five cards on table");
//			showCards();
		
			break;
		case 4:
			showCards();
			break;
		default: 
			break;
		}//every reset of game set count rounds to zero;
	}
	
	public void showCards(){
		System.out.println("Show Cards");

		for(int i = 0; i < pl.size(); i++){	
			pl.get(i).getHand().knowBestHand();
				if(pl.get(i).isHasFolded()){
					pl.get(i).getHand().setRankScore(0);
				}//end of folded
		}//end for

	//    ArrayList rankList = new ArrayList();
	  
	    for(int i = 0; i < pl.size(); i++){	
	    	rankList.add(pl.get(i).getHand().getRankScore()); //Add elements to rankList
	    }
	 
	    Object obj = Collections.max(rankList);
//	    int countTie = 0;
	    int winnerScore = (Integer) obj;	    
	    for(int i = 0; i < pl.size(); i++){	
	    
	    	if(winnerScore==pl.get(i).getHand().getRankScore()){
//	    		countTie++;
	    		this.pl.get(i).setWinner(true);
	    		this.pl.get(i).win(pot);
	    		System.out.println(this.pl.get(i).getName()+" "+this.pl.get(i).getHand().getCom());
	    	}else{
	    		System.out.print("No Winner");
	    	}
	    }
		System.out.println("Game has Ended");

	
		this.setNotOver(false);	
		this.setGameStarted(false);
	}
	
	public void nextActivePlayers(){
		
		do{
			this.nextPlayer();
			this.setCurrentPlayer();
		}while(this.getCurrentPlayer().isHasFolded());
	
	}
	
	public void nextPlayer(){
	 
		if(this.getPlayerNumber()<pl.size()-1){
			this.setPlayerNumber(getPlayerNumber() + 1);
		}else{
			this.setPlayerNumber(0);
		}
	 
	 
	}
	
	
	public void nextSmallBlind(){
		
		if(this.getSmallBlind()<pl.size()-1){
			this.setSmallBlind(getSmallBlind()+1);
		}else{
			this.setSmallBlind(0);
		}
	}
	
	public void nextBigBlind(){
		
		if(this.getBigBlind()<pl.size()-1){
			this.setBigBlind(getBigBlind()+1);	
		}else{
			this.setBigBlind(0);
		}
	}
	
	public void nextDealer(){
		
		if(this.getDealerNumber()<pl.size()-1){
			this.setDealerNumber(getDealerNumber()+1);
		}else{
			this.setDealerNumber(0);
		}
	}
	
	public Player getCurrentPlayer(){
		return this.currentPlayer;
	}

	public void setCurrentPlayer(){
		this.currentPlayer = pl.get(getPlayerNumber());
	}

	public int getPlayerNumber() {
		return playerNumber;
	}

	public void setPlayerNumber(int playerNumber) {
		this.playerNumber = playerNumber;
	}
	
	public Player getSmallBlindPlayer(){
		return this.smallPlayer;
	}
	
	public void setSmallBlindPlayer(){
		this.smallPlayer = pl.get(smallBlind);
	}

	public Player getBigBlindPlayer(){
		return this.bigPlayer;
	}
	
	public void setBigBlindPlayer(){
		this.bigPlayer = pl.get(bigBlind);
	}
	
	public Player getDealerPlayer(){
		return this.dealerPlayer;
	}
	
	public void setDealerPlayer(){
		this.dealerPlayer = pl.get(dealerNumber);
	}
	
	public int getDealerNumber() {
		return dealerNumber;
	}

	public void setDealerNumber(int dealerNumber) {
		this.dealerNumber = dealerNumber;
	}
	
	public int getSmallBlind() {
		return smallBlind;
	}

	public void setSmallBlind(int smallBlind) {
		this.smallBlind = smallBlind;
	}

	public int getBigBlind() {
		return bigBlind;
	}

	public void setBigBlind(int bigBlind) {
		this.bigBlind = bigBlind;
	}

	public boolean isGameStarted() {
		return gameStarted;
	}

	public void setGameStarted(boolean gameStarted) {
		this.gameStarted = gameStarted;
	}

	public int getMinimumBet() {
		return minimumBet;
	}

	public void setMinimumBet(int minimumBet) {
		this.minimumBet = minimumBet;
	}

	public int getPot() {
		return pot;
	}

	public void setPot(int pot) {
		this.pot = pot;
	}

	public int getRaiseBet() {
		return raiseBet;
	}

	public void setRaiseBet(int raiseBet) {
		this.raiseBet = raiseBet;
	}

	public boolean isBettingRound() {
		return bettingRound;
	}

	public void setBettingRound(boolean bettingRound) {
		this.bettingRound = bettingRound;
	}

	public int getCountRounds() {
		return countRounds;
	}

	public void setCountRounds(int countRounds) {
		this.countRounds = countRounds;
	}

	public boolean isNotOver() {
		return notOver;
	}

	public void setNotOver(boolean notOver) {
		this.notOver = notOver;
	}

	public ArrayList<Player> getPl() {
		return pl;
	}

	public void setPl(ArrayList<Player> pl) {
		this.pl = pl;
	}

	public boolean isResetGame() {
		return resetGame;
	}

	public void setResetGame(boolean resetGame) {
		this.resetGame = resetGame;
	}

}
